home *** CD-ROM | disk | FTP | other *** search
/ InterCD 2000 September / september_2000.iso / intercd / root / ^Linux / WindowMaker / wrlib / xpixmap.c < prev    next >
Encoding:
C/C++ Source or Header  |  2000-01-19  |  4.4 KB  |  181 lines

  1. /* xpixmap.c - Make RImage from Pixmap or XImage
  2.  * 
  3.  *  Raster graphics library
  4.  *
  5.  *  Copyright (c) 1997 Alfredo K. Kojima 
  6.  *
  7.  *  This library is free software; you can redistribute it and/or
  8.  *  modify it under the terms of the GNU Library General Public
  9.  *  License as published by the Free Software Foundation; either
  10.  *  version 2 of the License, or (at your option) any later version.
  11.  *  
  12.  *  This library is distributed in the hope that it will be useful,
  13.  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  14.  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  15.  *  Library General Public License for more details.
  16.  *  
  17.  *  You should have received a copy of the GNU Library General Public
  18.  *  License along with this library; if not, write to the Free
  19.  *  Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  20.  */
  21.  
  22.  
  23. #include <config.h>
  24.  
  25. #include <X11/Xlib.h>
  26. #include <X11/Xutil.h>
  27. #include <stdlib.h>
  28. #include <stdio.h>
  29. #include <string.h>
  30. #include <assert.h>
  31.  
  32. #include "wraster.h"
  33.  
  34.  
  35.  
  36. static int
  37. get_shifts(unsigned long mask)
  38. {
  39.     int i=0;
  40.     
  41.     while (mask) {
  42.     mask>>=1;
  43.     i++;
  44.     }
  45.     return i;
  46. }
  47.  
  48.  
  49. RImage*
  50. RCreateImageFromXImage(RContext *context, XImage *image, XImage *mask)
  51. {
  52.     RImage *img;
  53.     int x, y;
  54.     unsigned long pixel;
  55.     unsigned char *data;
  56.     int rshift, gshift, bshift;
  57.     int rmask, gmask, bmask;
  58.  
  59.     assert(image!=NULL);
  60.     assert(image->format==ZPixmap);
  61.     assert(!mask || mask->format==ZPixmap);
  62.     
  63.     img = RCreateImage(image->width, image->height, mask!=NULL);
  64.     if (!img) {
  65.     return NULL;
  66.     }
  67.       
  68.  
  69.     /* I don't know why, but XGetImage() for pixmaps don't set the
  70.      * {red,green,blue}_mask values correctly. 
  71.      */ 
  72.     if (context->depth==image->depth) {
  73.          rmask = context->visual->red_mask;
  74.         gmask = context->visual->green_mask;
  75.         bmask = context->visual->blue_mask;
  76.     } else {
  77.         rmask = image->red_mask;
  78.         gmask = image->green_mask;
  79.         bmask = image->blue_mask;
  80.     }
  81.  
  82.     /* how many bits to shift to normalize the color into 8bpp */
  83.     rshift = get_shifts(rmask) - 8;
  84.     gshift = get_shifts(gmask) - 8;
  85.     bshift = get_shifts(bmask) - 8;
  86.  
  87.     data = img->data;
  88.  
  89. #define NORMALIZE_RED(pixel)    ((rshift>0) ? ((pixel) & rmask) >> rshift \
  90.                     : ((pixel) & rmask) << -rshift)
  91. #define NORMALIZE_GREEN(pixel)    ((gshift>0) ? ((pixel) & gmask) >> gshift \
  92.                     : ((pixel) & gmask) << -gshift)
  93. #define NORMALIZE_BLUE(pixel)    ((bshift>0) ? ((pixel) & bmask) >> bshift \
  94.                     : ((pixel) & bmask) << -bshift)
  95.  
  96.     if (image->depth==1) {
  97.     for (y = 0; y < image->height; y++) {
  98.         for (x = 0; x < image->width; x++) {
  99.         pixel = XGetPixel(image, x, y);
  100.         if (pixel) {
  101.             *data++ = 0;
  102.             *data++ = 0;
  103.             *data++ = 0;
  104.         } else {
  105.             *data++ = 0xff;
  106.             *data++ = 0xff;
  107.             *data++ = 0xff;
  108.         }
  109.         }
  110.     }
  111.     } else {
  112.     for (y = 0; y < image->height; y++) {
  113.         for (x = 0; x < image->width; x++) {
  114.         pixel = XGetPixel(image, x, y);
  115.         *(data++) = NORMALIZE_RED(pixel);
  116.         *(data++) = NORMALIZE_GREEN(pixel);
  117.         *(data++) = NORMALIZE_BLUE(pixel);
  118.         }
  119.     }
  120.     }
  121.  
  122.  
  123. #define MIN(a,b) ((a)<(b)?(a):(b))
  124.     if (mask) {
  125.     for (y = 0; y < MIN(mask->height, image->height); y++) {
  126.         for (x = 0; x < MIN(mask->width, image->width); x++) {
  127.         if (XGetPixel(mask, x, y)) {
  128.             *(data++) = 0xff;
  129.         } else {
  130.             *(data++) = 0;
  131.         }
  132.         }
  133.     }
  134.     }
  135.     return img;
  136. }
  137.  
  138.  
  139.  
  140. RImage*
  141. RCreateImageFromDrawable(RContext *context, Drawable drawable, Pixmap mask)
  142. {
  143.     RImage *image;
  144.     XImage *pimg, *mimg;
  145.     unsigned int w, h, bar;
  146.     int foo;
  147.     Window baz;
  148.  
  149.  
  150.     assert(drawable!=None);
  151.     
  152.     if (!XGetGeometry(context->dpy, drawable, &baz, &foo, &foo, 
  153.               &w, &h, &bar, &bar)) {
  154.     printf("wrlib:invalid window or pixmap passed to RCreateImageFromPixmap\n");
  155.     return NULL;
  156.     }
  157.     pimg = XGetImage(context->dpy, drawable, 0, 0, w, h, AllPlanes, 
  158.              ZPixmap);
  159.     
  160.     if (!pimg) {
  161.     RErrorCode = RERR_XERROR;
  162.     return NULL;
  163.     }
  164.     mimg = NULL;
  165.     if (mask) {
  166.     if (XGetGeometry(context->dpy, mask, &baz, &foo, &foo, 
  167.               &w, &h, &bar, &bar)) {
  168.         mimg = XGetImage(context->dpy, mask, 0, 0, w, h, AllPlanes, 
  169.                  ZPixmap);
  170.     }
  171.     }
  172.  
  173.     image = RCreateImageFromXImage(context, pimg, mimg);
  174.  
  175.     XDestroyImage(pimg);
  176.     if (mimg)
  177.       XDestroyImage(mimg);
  178.  
  179.     return image;
  180. }
  181.